﻿namespace HZY.Repository.Admin;

/// <summary>
/// 后台管理系统数据库上下文
/// </summary>
[DbContextConfig($"Repository.*.Entities.*")]
public class AdminDbContext : DbContext, IBaseDbContext
{
    /// <summary>
    /// 工作单元
    /// </summary>
    public IUnitOfWork UnitOfWork { get; }

    private readonly IConfiguration _configuration;
    private readonly IWebHostEnvironment _webHostEnvironment;

    public AdminDbContext(
        DbContextOptions<AdminDbContext> dbContextOptions,
        IConfiguration configuration,
        IWebHostEnvironment webHostEnvironment) :
        base(dbContextOptions)
    {
        UnitOfWork = new UnitOfWorkImpl<AdminDbContext>(this);
        _configuration = configuration;
        _webHostEnvironment = webHostEnvironment;
    }

    /// <summary>
    /// 获取仓储配置
    /// </summary>
    /// <returns></returns>
    /// <exception cref="Exception"></exception>
    public RepositoryOptions GetRepositoryOptions()
    {
        var repositoryOptions = _configuration
      .GetSection(nameof(AdminRepositoryOptions))
      .Get<AdminRepositoryOptions>() ?? throw new Exception("配置对象 空 异常！");

        return repositoryOptions;
    }

    /// <summary>
    /// 配置
    /// </summary>
    /// <param name="optionsBuilder"></param>
    /// <exception cref="Exception"></exception>
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        var repositoryOptions = this.GetRepositoryOptions();

        // 获取连接字符串
        var connectionString = repositoryOptions.ConnectionString;
        connectionString = string.IsNullOrWhiteSpace(connectionString) ?
            _configuration["ConnectionStrings:" + repositoryOptions!.DefaultDatabaseType.ToString()] :
            connectionString;

        switch (repositoryOptions.DefaultDatabaseType)
        {
            case DefaultDatabaseType.SqlServer:
                optionsBuilder
               .UseSqlServer(connectionString, w => w.MinBatchSize(1).MaxBatchSize(1000))
               ;
                break;
            case DefaultDatabaseType.MySql:
                optionsBuilder
               .UseMySql(connectionString, MySqlServerVersion.LatestSupportedServerVersion, w => w.MinBatchSize(1).MaxBatchSize(1000))
               ;
                break;
            case DefaultDatabaseType.PostgreSql:
                optionsBuilder
                .UseNpgsql(connectionString, w => w.MinBatchSize(1).MaxBatchSize(1000))
                ;
                break;
            case DefaultDatabaseType.Oracle:
                optionsBuilder
                .UseOracle(connectionString, w => w.MinBatchSize(1).MaxBatchSize(1000))
                ;
                break;
            default:
                break;
        }

        if (_webHostEnvironment.IsDevelopment())
        {
            // sql 日志写入控制台
            var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole(configure =>
            {
                configure.LogToStandardErrorThreshold = LogLevel.Error;
            }));
            optionsBuilder.UseLoggerFactory(loggerFactory)
            //.EnableDetailedErrors()
            //.EnableSensitiveDataLogging(true)
            ;
        }

        // 懒加载代理
        //options.UseLazyLoadingProxies();
        //添加 EFCore 监控 和 动态表名
        optionsBuilder.AddEntityFrameworkMonitor(repositoryOptions.IsMonitorEFCore);
        optionsBuilder.AddInterceptors(new AuditInterceptor());
    }

    /// <summary>
    /// 模型创建
    /// </summary>
    /// <param name="modelBuilder"></param>
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        var dbContextConfigAttribute = GetType().GetCustomAttribute<DbContextConfigAttribute>()!;
        dbContextConfigAttribute!.OnModelCreating(modelBuilder, dbContextConfigAttribute.GetModelTypes(GetType()));

        #region 自动迁移种子数据

        //ModelBuilderExtensions.Seed(modelBuilder);

        #endregion
    }


}
